using Sage.Http.Models;

namespace Sage.Http.Extensions
{
    /// <summary>
    /// HTTP响应消息的扩展方法
    /// </summary>
    public static partial class HttpResponseMessageExtensions
    {
        /// <summary>
        /// 获取响应头中的Location值
        /// </summary>
        public static string? GetLocationHeader(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Headers.Location?.ToString();
        }

        /// <summary>
        /// 获取内容类型
        /// </summary>
        public static string? GetContentType(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Content?.Headers.ContentType?.MediaType;
        }

        /// <summary>
        /// 获取内容长度
        /// </summary>
        public static long? GetContentLength(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Content?.Headers.ContentLength;
        }

        /// <summary>
        /// 获取ETag值（用于缓存验证）
        /// </summary>
        public static string? GetETag(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Headers.ETag?.Tag;
        }

        /// <summary>
        /// 获取最后修改时间
        /// </summary>
        public static DateTimeOffset? GetLastModified(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);
            return response.Content?.Headers.LastModified;
        }

        /// <summary>
        /// 获取API速率限制信息
        /// </summary>
        /// <param name="response">HTTP响应消息</param>
        /// <returns>速率限制信息</returns>
        public static RateLimitInfo GetRateLimitInfo(this HttpResponseMessage response)
        {
            var info = new RateLimitInfo();

            // 使用 Span<T> 优化字符串操作
            if (response.Headers.TryGetValues("X-RateLimit-Limit", out var limitValues))
            {
                var limitValue = limitValues.FirstOrDefault();
                if (!string.IsNullOrEmpty(limitValue) && int.TryParse(limitValue.AsSpan(), out var limit))
                {
                    info.Limit = limit;
                }
            }

            if (response.Headers.TryGetValues("X-RateLimit-Remaining", out var remainingValues))
            {
                var remainingValue = remainingValues.FirstOrDefault();
                if (!string.IsNullOrEmpty(remainingValue) && int.TryParse(remainingValue.AsSpan(), out var remaining))
                {
                    info.Remaining = remaining;
                }
            }

            if (response.Headers.TryGetValues("X-RateLimit-Reset", out var resetValues))
            {
                var resetValue = resetValues.FirstOrDefault();
                if (!string.IsNullOrEmpty(resetValue) && long.TryParse(resetValue.AsSpan(), out var resetTimestamp))
                {
                    info.ResetTime = DateTimeOffset.FromUnixTimeSeconds(resetTimestamp);
                }
            }

            return info;
        }

        /// <summary>
        /// 获取重试等待时间（秒）
        /// </summary>
        public static int? GetRetryAfterSeconds(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);

            if (response.Headers.RetryAfter == null)
                return null;

            if (response.Headers.RetryAfter.Delta.HasValue)
                return (int)response.Headers.RetryAfter.Delta.Value.TotalSeconds;

            if (response.Headers.RetryAfter.Date.HasValue)
            {
                var timeToWait = response.Headers.RetryAfter.Date.Value - DateTimeOffset.UtcNow;
                return (int)Math.Max(0, timeToWait.TotalSeconds);
            }

            return null;
        }

        /// <summary>
        /// 获取分页链接（从Link头）
        /// </summary>
        public static Dictionary<string, string> GetPaginationLinks(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);

            var links = new Dictionary<string, string>();

            if (!response.Headers.TryGetValues("Link", out var linkValues) || linkValues == null)
                return links;

            foreach (var link in linkValues)
            {
                // 使用 ReadOnlySpan<char> 优化字符串解析
                var linkSpan = link.AsSpan();

                // 链接格式示例：<https://api.example.com/items?page=2>; rel="next"
                var semicolonIndex = linkSpan.IndexOf(';');
                if (semicolonIndex == -1)
                    continue;

                var urlSegment = linkSpan[..semicolonIndex].Trim();
                var relSegment = linkSpan[(semicolonIndex + 1)..].Trim();

                if (urlSegment.Length > 2 && urlSegment[0] == '<' && urlSegment[^1] == '>' &&
                    relSegment.StartsWith("rel=".AsSpan(), StringComparison.Ordinal))
                {
                    var url = urlSegment[1..^1].ToString(); // 去掉 < 和 >
                    var relMatch = MyRegex().Match(relSegment.ToString());
                    if (relMatch.Success)
                    {
                        var rel = relMatch.Groups[1].Value;
                        links[rel] = url;
                    }
                }
            }

            return links;
        }

        /// <summary>
        /// 获取请求ID（用于跟踪和调试）
        /// </summary>
        public static string? GetRequestId(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);

            // 方法1：使用显式类型的数组声明
            foreach (var headerName in new[] { "X-Request-ID", "X-Correlation-ID", "Request-ID", "X-Trace-ID" })
            {
                var value = GetHeaderValue(response, headerName);
                if (!string.IsNullOrEmpty(value))
                    return value;
            }

            // 方法2：使用C# 12的类型前缀语法 (也可以使用)
            // foreach (var headerName in string[] ["X-Request-ID", "X-Correlation-ID", "Request-ID", "X-Trace-ID"])

            // 方法3：先声明变量，再使用 (也可以使用)
            // string[] requestIdHeaders = ["X-Request-ID", "X-Correlation-ID", "Request-ID", "X-Trace-ID"];
            // foreach (var headerName in requestIdHeaders)

            return null;
        }

        /// <summary>
        /// 尝试获取指定的响应头值
        /// </summary>
        public static string? GetHeaderValue(this HttpResponseMessage response, string headerName)
        {
            ArgumentNullException.ThrowIfNull(response);
            ArgumentException.ThrowIfNullOrEmpty(headerName);

            if (response.Headers.TryGetValues(headerName, out IEnumerable<string>? values) && values != null)
            {
                return values.FirstOrDefault();
            }

            // 有些头部可能在Content.Headers中
            if (response.Content?.Headers.TryGetValues(headerName, out values) == true && values != null)
            {
                return values.FirstOrDefault();
            }

            return null;
        }

        /// <summary>
        /// 获取所有响应头
        /// </summary>
        public static Dictionary<string, string> GetAllHeaders(this HttpResponseMessage response)
        {
            ArgumentNullException.ThrowIfNull(response);

            var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            // 添加响应头
            foreach (var header in response.Headers)
            {
                headers[header.Key] = string.Join(", ", header.Value);
            }

            // 添加内容头
            if (response.Content != null)
            {
                foreach (var header in response.Content.Headers)
                {
                    headers[header.Key] = string.Join(", ", header.Value);
                }
            }

            return headers;
        }

        [System.Text.RegularExpressions.GeneratedRegex("rel=[\"']?([^\"']+)[\"']?")]
        private static partial System.Text.RegularExpressions.Regex MyRegex();
    }
}